package com.baidu.mpks.common;

import com.baidu.mpks.role.dto.RoleDto;
import org.redisson.Redisson;
import org.redisson.api.*;
import org.redisson.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class RedisClient {
    private static final Logger log = LoggerFactory.getLogger(RedisClient.class);
    private static volatile RedisClient instance;
    private RedissonClient redisson;

    public RedisClient() {
        ClassLoader classloader = Thread.currentThread().getContextClassLoader();

        try {
            Config config = Config.fromYAML(classloader.getResourceAsStream("redis.yaml"));
            this.redisson = Redisson.create(config);
        } catch (IOException var4) {
            log.error("construct redis client failed");
        }

    }

    public static RedisClient getInstance() {
        if (instance == null) {
            Class var0 = RedisClient.class;
            synchronized(RedisClient.class) {
                if (instance == null) {
                    instance = new RedisClient();
                }
            }
        }

        return instance;
    }

    public void shutdown() {
        this.redisson.shutdown();
    }

    public <T> T get(String key) {
        RBucket<T> bucket = this.redisson.getBucket(key);
        return bucket.get();
    }

    public Map<String, Map<String, Object>> getMapByKey(String key) {
        RBucket<Map<String, Map<String, Object>>> bucket = this.redisson.getBucket(key);
        return (Map)bucket.get();
    }

    public Map<String, Object> getMapByKeyV3(String key) {
        RBucket<Map<String, Object>> bucket = this.redisson.getBucket(key);
        return (Map)bucket.get();
    }

    public RoleDto getRoleDtoByKey(String key) {
        RBucket<RoleDto> bucket = this.redisson.getBucket(key);
        return (RoleDto)bucket.get();
    }

    public Iterable<String> getKeys() {
        return this.redisson.getKeys().getKeys();
    }

    public Iterable<String> getKeysByPattern(String keyword) {
        return this.redisson.getKeys().getKeysByPattern("*" + keyword + "*");
    }

    public int delete(String key) {
        RKeys keys = this.redisson.getKeys();
        return keys.delete(new String[]{key}) > 0L ? 1 : 0;
    }

    public int deleteByPattern(String pattern) {
        RKeys keys = this.redisson.getKeys();
        return keys.deleteByPattern(pattern) > 0L ? 1 : 0;
    }

    public <T> void setKey(String key, T value) {
        RBucket<T> bucket = this.redisson.getBucket(key);
        bucket.set(value);
    }

    public <T> void setKey(String key, T value, int exp, TimeUnit timeUnit) {
        RBucket<T> bucket = this.redisson.getBucket(key);
        bucket.set(value, (long)exp, timeUnit);
    }

    public void setKey(String key, RoleDto value, int exp, TimeUnit timeUnit) {
        RBucket<RoleDto> bucket = this.redisson.getBucket(key);
        bucket.set(value, (long)exp, timeUnit);
    }

    public <T> boolean trySet(String key, T value) {
        RBucket<T> bucket = this.redisson.getBucket(key);
        return bucket.trySet(value);
    }

    public void setKeyV3(String key, Map<String, Object> value, int exp, TimeUnit timeUnit) {
        RBucket<Map<String, Object>> bucket = this.redisson.getBucket(key);
        bucket.set(value, (long)exp, timeUnit);
    }

//    public List<Object> batchGet(List<String> keys) {
//        RBatch batch = this.redisson.createBatch();
//        Iterator var3 = keys.iterator();
//
//        while(var3.hasNext()) {
//            String key = (String)var3.next();
//            batch.getBucket(key).getAsync();
//        }
//
//        BatchResult<?> f = batch.execute();
//        return f.getResponses();
//    }

    public void batchDelete(List<String> keys) {
        RBatch batch = this.redisson.createBatch();
        Iterator var3 = keys.iterator();

        while(var3.hasNext()) {
            String key = (String)var3.next();
            batch.getBucket(key).deleteAsync();
        }

        batch.execute();
    }

    public boolean lock(String key, int expr, TimeUnit timeUnit) {
        RLock rLock = this.redisson.getLock(key);

        try {
            return rLock.tryLock(0L, (long)expr, timeUnit);
        } catch (Exception var6) {
            log.error("lock error key{},e{}", key, var6);
            return true;
        }
    }

    public void unLock(String key) {
        RLock rLock = this.redisson.getLock(key);
        if (rLock.isHeldByCurrentThread()) {
            rLock.unlock();
        }

    }

    public boolean isLocked(String key) {
        RLock rLock = this.redisson.getLock(key);
        return rLock.isLocked();
    }

    public String setCache(String cacheName, String cacheKey, String cacheValue, long times, TimeUnit timeUnit) {
        RMap<String, String> map = this.redisson.getMap(cacheName);
        map.put(cacheKey, cacheValue);
        map.expire(times, timeUnit);
        return (String)map.get(cacheKey);
    }

    public String setCache(String cacheName, String cacheKey, String cacheValue) {
        RMap<String, String> map = this.redisson.getMap(cacheName);
        map.put(cacheKey, cacheValue);
        return (String)map.get(cacheKey);
    }

    public String getCache(String cacheName, String cacheKey) {
        RMap<String, String> map = this.redisson.getMap(cacheName);
        return map == null ? null : (String)map.get(cacheKey);
    }
}